package HTTP

import (
	"SQL/myDB"
	"database/sql"
	"encoding/json"
	"net/http"
	"time"
)

//创建群：
//s nickname string,icon string,customInfo dictionary
//r Message string,
//  groupID
func addGroup(w http.ResponseWriter, req *http.Request) {
	var (
		code   int         = Success
		msg    string      = ""
		result interface{} = nil
	)
	defer func() {
		writeResponse(code, msg, result, w)
	}()

	err := initHandle(w, req)
	if err != nil {
		code = errParseForm
		msg = err.Error()
		return
	}

	//若有默认值要在这里设
	userID := req.FormValue("userID")
	nickname := req.FormValue("nickname")
	icon := req.FormValue("icon")
	memberID := req.Form["memberID"]
	delete(req.Form, "nickname")
	delete(req.Form, "icon")
	delete(req.Form, "memberID")
	delete(req.Form, "userID")
	requestJson := initRequestJson(req.Form)
	customInfo, err := json.Marshal(requestJson)
	if err != nil {
		code = errMarshalJSONFailed
		msg = err.Error()
		return
	}

	code, msg, result = dealAddGroup(nickname, icon, customInfo, memberID, userID)
}
func dealAddGroup(nickname string, icon string, customInfo interface{}, memberID []string, userID string) (code int, msg string, result interface{}) {
	if userID == "" {
		code = errEmtpyID
		msg = "userID is empty"
		return
	}
	code, msg = IsManager(userID)
	if code != Success {
		return
	}

	if nickname == "" {
		code = errEmptyParameter
		msg = "nickname is empty"
		return
	}

	if icon == "" {
		icon = "icon"
	}

	db, err := myDB.GetDB()
	if err != nil {
		code = errOpenDB
		msg = err.Error()
		return
	}

	code, msg = judgeMembers(db, memberID)
	if code != Success {
		return
	}

	tx, err := db.Begin()
	if err != nil {
		code = errBeginTx
		msg = err.Error()
		return
	}

	defer func() {
		if code != Success {
			err := tx.Rollback()
			if err != nil {
				code = errEndTx
				msg = err.Error()
			}
		}
	}()

	code, msg, groupID := insertIntoObjects(tx, nickname, icon, customInfo, false)
	if code != Success {
		return
	}

	err = myDB.TxExecSql(tx, "insert into groups(id,createTime) values($1,$2)", groupID, time.Now())
	if err != nil {
		code = errDBExecFailed
		msg = err.Error()
		return
	}

	if memberID == nil {
		memberID = []string{}
	}
	memberID = append(memberID, userID)
	err = myDB.TxExecMultiSql(tx, "insert into members(groupID,userID) values($2,$1)", memberID, groupID)
	if err != nil {
		code = errDBExecFailed
		msg = err.Error()
		return
	}

	err = tx.Commit()
	if err != nil {
		code = errEndTx
		msg = err.Error()
		return
	}
	return Success, "", groupID
}

func insertIntoObjects(tx *sql.Tx, nickname string, icon string, customInfo interface{}, isUser bool) (code int, msg string, ID int64) {
	stmt, rows, err := myDB.TxQuerySql(tx, `
	insert into objects(nickname,icon,custom,isUser)
	values ($1,$2,$3,$4) returning id
	`, nickname, icon, customInfo, isUser)
	defer stmt.Close()
	defer rows.Close()
	if err != nil {
		code = errDBQueryFailed
		msg = err.Error()
		return
	}

	if !rows.Next() {
		code = errDBQueryFailed
		msg = "no rows"
		return
	}

	err = rows.Scan(&ID)
	if err != nil {
		code = errRowsScan
		msg = err.Error()
		return
	}
	code = Success
	msg = ""
	return
}

func IsManager(userID string) (code int, msg string) {
	rows, err := myDB.QuerySql("select isManager from users where id=$1", userID)
	defer rows.Close()
	if err != nil {
		code = errDBQueryFailed
		msg = err.Error()
		return
	}
	if !rows.Next() {
		code = errInvalidID
		msg = "userID not exist"
		return
	}
	var isManager bool
	err = rows.Scan(&isManager)
	if err != nil {
		code = errRowsScan
		msg = err.Error()
		return
	}
	if !isManager {
		code = errNoPermission
		msg = "userID is not Manager"
		return
	}
	return Success, ""
}
